package com.ly.consumer.function;


import com.ly.consumer.function.bienum.EnumTest;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

import java.util.*;
import java.util.function.*;
import java.util.stream.Collectors;

//java的以一些函数式接口训练
public class BiFunctionTest {



    //Consumer<T> 接收一个参数 并且没有返回值的操作
    private static int consumerVoid(int a, Consumer<Integer> then){
        int sum = a+1;
        if(then!=null){
            //注：这里接收的参数可以通过这里组装参数 返回给调用方使用
            then.accept(sum);
        }
        return sum;
    }

    //BiConsumer<T, U> 接收连个参数 且没有返回值操作
    private  static  int biConsumerVoid(int a, BiConsumer<Integer,Integer> then){
        int sum = a+1;
        if(then!=null){
            //注：这里接收的参数可以通过这里组装参数 返回给调用方使用
            then.accept(sum,0);
        }
        return sum;
    }

    //BiFunction<T,U,R> 接收两个参数 并且根据参数返回一个结果
    private static  Map biFunction(int a, BiFunction<Integer,Integer,Integer> then){
        Map map = new HashMap<>();
        int sum = a+1;
        if(then!=null){
            Integer apply = then.apply(sum, 0);
            map.put("apply",apply);
        }
        map.put("sum",sum);
        return map;
    }



    /**BinaryOperator是Java 8中的一个函数式接口，它继承自BiFunction接口，
     并且参数类型和返回类型相同。它的方法是apply(T t, T u)，用于对给定的两个参数执行某种操作，并返回结果。
    BinaryOperator通常用于需要对两个参数进行操作并产生相同类型结果的场景。
    它可以用于对两个值进行相加、相乘、取最大值、取最小值等操作。也可以将两个集合合成一个集合*/
    private static List<String> binaryOperator(List<String> list1,List<String> list2){
        BinaryOperator<List<String>> then = (x,y)->{
            List<String> mergedList = new ArrayList<>();
            mergedList.addAll(list1);
            mergedList.addAll(list2);
            return mergedList;
        };
        return then.apply(list1,list2);
    }










    public static void main(String[] args) {
        /**
         BiFunctionTest.consumerVoid(3,item->{
         //后续的操作，如果没有则传null
         System.out.println(item);
         });
         BiFunctionTest.biConsumerVoid(3,(item,item1)->{
         //后续的操作，如果没有则传null
         System.out.println(item);
         System.out.println(item1);
         });
         Map map = BiFunctionTest.biFunction(3, (item, item1) -> {
         //后续的操作，如果没有则传null
         System.out.println(item);
         System.out.println(item1);
         //这里要放一个方法 用于操作输入的的参数并且返回特定返回值
         return item + item1;
         });
         System.out.println(map);**/
        /**
         //筛选出电影集合里面成龙的电影并且返回电影信息 使用函数式接口
         //方法1
         BiFunction<String,List<Movies>,List<Movies>> filter =
         (x,y)->  y.stream().filter(yitem->Objects.equals(yitem.getProtagonist(),x)).collect(Collectors.toList());
         List<Movies> result1 = filter.apply("贾玲", mockData());
         //方法2 直接配置在枚举里
         BiPredicate<String,String> filter1 = (x,y)-> Objects.equals(x,y);
         List<Movies> list1 = mockData();
         List<Movies> result2 = list1.stream().filter(item -> EnumTest.MOVES_PROTAGONIST.filter1.test("成龙", item.getProtagonist())).collect(Collectors.toList());
         System.out.println(result2);*/

        /** //binaryOperator 操作
         List<String> list1 = Arrays.asList("1","2");
         List<String> list2 = Arrays.asList("3","4");
         List<String> list = BiFunctionTest.binaryOperator(list1, list2);
         System.out.println(list);*/

        /** //自定义函数接口
         CustomFunction<Integer, Integer, Integer, Integer> customFunction = (x, y, z) -> x+y+z;
         Integer apply = customFunction.apply(3, 2, 3);
         System.out.println(apply);*/
    }





    public static List<Movies> mockData(){
        return Arrays.asList(new Movies("警察故事", "成龙", "2001-10-11",123000.00),
                new Movies("飞驰人生", "沈腾", "2022-10-10",2000000.0),
                new Movies("你好李焕英", "贾玲", "2022-10-10",3000000.0),
                new Movies("缝纫机乐队", "大鹏", "2018-10-11",4000000.0),
                new Movies("警察故事Ⅱ", "成龙", "2002-10-11",4000000.0));
    }


    @Getter
    @Setter
    @AllArgsConstructor
    static
    class Movies{
        //电影名称
        private String name;
        //主角
        private String protagonist;
        //上映时间
        private String releaseTime;
        //票房
        private Double boxOffice;

        @Override
        public String toString() {
            return "Movies{" +
                    "name='" + name + '\'' +
                    ", protagonist='" + protagonist + '\'' +
                    ", releaseTime='" + releaseTime + '\'' +
                    ", boxOffice=" + boxOffice +
                    '}';
        }
    }
}
